"""
@Author:lichuang
@Create: 2024/10/15
@Last Modified: 2024/10/15
@Last Editor:
@Filename: authentication.py
@Description:
"""
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
import jwt
from apps.user.models import SysUser
from django.conf import settings

class User:
    """自定义用户类，实现存储用户信息"""
    def __init__(self, user_id, username,token,user_object=None):
        """初始化"""
        self.user_id = user_id
        self.username = username
        self.token = token
        self.user_object = user_object  # 存储用户对象


class TokenAuthentication(BaseAuthentication):
    """
    自定义 DRF 认证类，用于通过 JWT token 验证/获取用户身份。
    """
    def authenticate(self, request):
        """
        验证请求中的 JWT Token。

        Args:
           request (Request): 当前 HTTP 请求对象。

        Returns:
           (None, token) 或者 抛出 AuthenticationFailed 异常

        Raises:
           AuthenticationFailed: 如果请求中缺少 Authorization 头，token 无效或解码失败，抛出此异常。
        """
        #白名单列表
        whitelist_urls= [
            'api/user/login/',
            # 添加更多不需要认证的URL
        ]

        # if request.method in ['post','POST'] and request.path.lower() in whitelist_urls:
        #     return None,None

        # 获取请求头 Authorization
        auth_header = request.headers.get('Authorization')

        if not auth_header:
            raise AuthenticationFailed('缺少token，认证失败')

        # 确保 Authorization 头的格式为 "Bearer <token>"
        try:
            prefix, token = auth_header.split(' ')
            if prefix.lower() != 'bearer':
                raise AuthenticationFailed('Authorization header must start with Bearer')
        except ValueError:
            raise AuthenticationFailed('Invalid Authorization header format')

        try:
            # 使用密钥解码 JWT oa的密钥
            decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])

            # 在解码的 token 中获取用户信息
            user_id = decoded_token.get('user_id')
            # 这里可以根据 user_id 查询数据库或其他存储来验证用户权限
            # 获取并验证用户表中是否有此用户
            user_object = SysUser.objects.filter(id=user_id).first()
            if user_object is None:
                raise AuthenticationFailed('用户不存在,认证失败！')
            username = decoded_token.get('username')
            # 根据用户信息判断是否授予访问权限
            # 使用自定义 User 类
            request.user = User(user_id, username, token,user_object=user_object)

            # 返回 None 表示不与 Django 的 User 模型关联
            return request.user, None

        # 异常处理
        except jwt.ExpiredSignatureError:
            raise AuthenticationFailed('token失效')
        except jwt.DecodeError:
            raise AuthenticationFailed('token解析错误')
        except Exception as e:
            raise AuthenticationFailed(f'token认证失败: {str(e)}')
